library(trajr)
library(tidyverse)
library(readxl)
library(kableExtra)
library (patchwork)
# library(lessR)
ajay_page1 <- read_excel("./Data/velocity_5seq_20200219a.xlsx", col_names = T,
sheet = "velocity_5seq_20200219", range = "A1:AB23")%>%
rename("filename" = "f-name") %>%
mutate(filename = str_replace(filename, ".$", "")) %>%
rename("contact" = Seq3...15) %>%
mutate(firstMoveFrame = frame1 - posFile_start)
# View(ajay_page1)
ajay_page2 <- read_excel("./Data/velocity_5seq_20200219a.xlsx", sheet = "accl_sp_2020_May_07", range = "A1:N23")%>%
rename("filename" = 1,
"start_F" = `start-F`) %>%
mutate(filename = str_replace(filename, ".$", ""))
# Grab the names of all the files in the working directory as set above
all_pos <- list.files("./Data2", pattern =".pos", full.names = TRUE)
# Grabs the names of the video files from the control spreadsheet
# note the current directory only contains videos from the chronos camera
input_list <- ajay_page1 %>%
select("filename") %>%
pull()
# input_list
# creates a single object to be used as a pattern to grab the pos files that match those in the spreadsheet
pattern <- paste(input_list, sep="", collapse="|")
# list of pos files that match names in the spreadsheets
chosen_pos <- all_pos[grepl(pattern, all_pos)]
# first containers --------------------------------------------------------
# coord_files <- chosen_pos %>%
# str_subset(pattern = "-(\\d){2}.pos$")
coord_files <- chosen_pos %>%
str_subset(pattern = "(\\d|\\d_fail)\\.pos$")
# scale_files <- chosen_pos %>%
# str_subset(pattern = "_(\\d){2}mm.pos$")
scale_files <- chosen_pos %>%
str_subset(pattern = "(\\d){1,}_scale_(\\d){1,}(mm)|(\\d){1,}_fail_scale_(\\d){1,}(mm)\\.pos$")
# extract the known distances from the scale files
the_scales <- scale_files %>%
as.data.frame() %>%
rename("scaleFiles" = ".") %>%
mutate(scaleValues = str_extract(scaleFiles, pattern = "_(\\d){1,2}mm")) %>%
mutate(scaleValues = str_extract(string = scaleValues, pattern = "_\\d+")) %>%
mutate(scaleValues = str_replace(scaleValues, pattern = "_", replacement = "0.0")) %>%
mutate(scaleValues = as.numeric(scaleValues))
derivs_list <- pmap(list(coord_files, scale_files, the_scales$scaleValues), loadSample_FromList2) %>%
map(TrajSmoothSG, p = 5, n = 23) %>%
map(TrajDerivatives) %>%
set_names(mylabelseq("Derivs_", 1, 22, 1))
derivs_names <- names(derivs_list)
for(i in seq_along(derivs_names)) {
derivs_list[[i]] %>% plotSpeed()
title(derivs_names[i])
}
Exploration of the trajectory and speed change of the third high speed video showed an usual pattern. Further revision of the video showed that this was a failed attacked trigger towards an ant at a greater distance. Thus, the ant slayer spider did not attempt to tag the ant prey with silk. For this, the sequence is excluded.
trajs_list <- list(coords = coord_files, scales = scale_files, scaleValues = the_scales)
traj_03 <- loadSample_FromList(listObject = trajs_list, number = 3)
par(mfrow = c(1,2))
derivs_list$Derivs_03 %>% plotSpeed()
plot(traj_03, lwd = 1, lty = 1)
The following trajectories do not fit general settings applied to the rest of the trajectories and are thus using particular settings shown below (section “Distinct ones”).
removables <- c(2, 3, 12)
derivs_list_short <- derivs_list[- removables]
derivs_names_short <- derivs_names[- removables]
# names(derivs_list_short) <- derivs_names_short
# The "IndexLimitsManual" function pulls the index position of the following frames:
# last frame where speed is zero (the onset of the ant slayer attack)
# frame where the acrobatic strike reaches its maxumum speed
# default values used for the function
# IndexLimitsManual(derivs_object = derivs_list_sample$Derivs_01, startThreshold = 1e-8, thresholdFrame = 1, limit_range = 155, window_size = 35)
indexes_short <- map(derivs_list_short, IndexLimitsManual)
names(indexes_short)
## [1] "Derivs_01" "Derivs_04" "Derivs_05" "Derivs_06" "Derivs_07" "Derivs_08"
## [7] "Derivs_09" "Derivs_10" "Derivs_11" "Derivs_13" "Derivs_14" "Derivs_15"
## [13] "Derivs_16" "Derivs_17" "Derivs_18" "Derivs_19" "Derivs_20" "Derivs_21"
## [19] "Derivs_22"
The following plots show the speed change during the first phase of the attack (acrobatic strike) The blue vertical line marks the onset of the spiders’ attack (the spider begins moving) The red line shows where the peak speed was reached during the acrobatic strike Note this is restricted to the speeds achieved by the spiders while directing its attack to the ant prey and before dropping off from the trunk surface.
pmap(list(derivs_list_short, as.list(names(derivs_list_short)), indexes_short),
~ggplot() + geom_line(aes(x= ..1$speedTimes*1000, y= ..1$speed*100)) +
ggtitle(..2) +
geom_vline(xintercept = ..3$`maxim(um/a)`*4, col = "red")+
geom_vline(xintercept = c(..3$start_index)*4, col = "blue") +
xlab("Time (ms)") +
ylab("Speed (cm/s)") +
theme_bw()
)
## $Derivs_01
##
## $Derivs_04
##
## $Derivs_05
##
## $Derivs_06
##
## $Derivs_07
##
## $Derivs_08
##
## $Derivs_09
##
## $Derivs_10
##
## $Derivs_11
##
## $Derivs_13
##
## $Derivs_14
##
## $Derivs_15
##
## $Derivs_16
##
## $Derivs_17
##
## $Derivs_18
##
## $Derivs_19
##
## $Derivs_20
##
## $Derivs_21
##
## $Derivs_22
Trajectories 02 and 12 were affected by noisy speed curves before the onset of the attack. These were adjusted and corroborated with visual inspection of the videos to make sure that the selected frame was the last one before the attack onset.
# removables <- c(2, 3, 12)
derivs_list_special <- derivs_list[removables]
derivs_names_special <- derivs_names[removables]
names(derivs_list_special) <- derivs_names_special
# str(derivs_list_special)
Derivs 02
# get index frames
indexes_derivs_02 <- IndexLimitsManual(derivs_object = derivs_list_special$Derivs_02, startThreshold = 1e-8, thresholdFrame = 19, limit_range = 155, window_size = 25)
# plot
ggplot() +
geom_line(aes(x = derivs_list_special$Derivs_02$speedTimes*1000, y = derivs_list_special$Derivs_02$speed*100)) +
geom_vline(xintercept = indexes_derivs_02$`maxim(um/a)`[2]*4, col = "red") +
geom_vline(xintercept = c(indexes_derivs_02$start_index, indexes_derivs_02$end_index)*4, col = "blue") +
labs(title = "Derivs_02",
x = "Time (ms)",
y = "Speed (cm/s)") +
theme_minimal()
# indexes_derivs_02$`maxim(um/a)`
# indexes_derivs_02$end_index
Derivs 12
# get index frames
indexes_derivs_12 <- IndexLimitsManual(derivs_object = derivs_list_special$Derivs_12, startThreshold = 1e-8, thresholdFrame = 19, limit_range = 155, window_size = 35)
# plot
ggplot() +
geom_line(aes(x = derivs_list_special$Derivs_12$speedTimes*1000, y = derivs_list_special$Derivs_12$speed*100)) +
geom_vline(xintercept = indexes_derivs_12$`maxim(um/a)`*4, col = "red") +
geom_vline(xintercept = c(indexes_derivs_12$start_index, indexes_derivs_12$end_index)*4, col = "blue") +
labs(title = "Derivs_12",
x = "Time (ms)",
y = "Speed (cm/s)") +
theme_minimal()
# indexes_derivs_02$`maxim(um/a)`
# indexes_derivs_02$end_index
Panel F in figure 1
The figure plots the speed change from the last frame before the acrobatic attack onset to the maximum speed reached for 17/19 inspected high speed videos. The remaining 2 (02 and 12) are added later.
# loop me up!
# colour palette
cbp1 <- c("#999999", "#E69F00", "#56B4E9", "#009E73",
"#F0E442", "#0072B2", "#D55E00", "#CC79A7")
# to recycle colours
cbp1_24 <- rep(cbp1, 3)
mp <- ggplot()
for(i in seq_along(derivs_list_short)) {
idata <- tibble("speed" = derivs_list_short[[i]]$speed[indexes_short[[i]]$start_index:indexes_short[[i]]$`maxim(um/a)`]) %>%
mutate("index" = seq_along(speed)-1)
mp <- mp + geom_line(data = idata,
aes(x = index*4, y = speed*100), colour = cbp1_24[i]) +
geom_point(data = idata,
aes(x = last(index)*4,
y = last(speed*100)),
colour = cbp1_24[i]) +
expand_limits(x = c(0, 160), y = c(0, 65)) +
ylab("Speed (cm/s)") +
xlab("Time (ms)") +
theme_classic() +
theme(panel.border = element_blank())
}
# the version below does not include speed for trajectories 02 and 12
# print(mp)
# mp +
# scale_y_continuous(expand = expansion(mult = c(0, .1))) +
# scale_x_continuous(expand = expansion(mult = c(0, .1)))
Curves for trajectories 02 and 12 are created with the distinct settings created before to capture the correct frames of importance
# 02
derivs_02_data <- tibble("speed" = derivs_list_special$Derivs_02$speed[indexes_derivs_02$start_index:indexes_derivs_02$`maxim(um/a)`[2]]) %>%
mutate("index" = seq_along(speed)-1)
mp <- mp +
geom_line(data = derivs_02_data,
aes(x = index*4, y = speed*100), colour = cbp1_24[7]) +
geom_point(data = derivs_02_data,
aes(x = last(index)*4,
y = last(speed*100)),
colour = cbp1_24[7]) +
expand_limits(x = c(0, 160), y = c(0, 65)) +
ylab("Speed (cm/s)") +
xlab("Time (ms)") +
theme_bw()
# 12
derivs_12_data <- tibble("speed" = derivs_list_special$Derivs_12$speed[indexes_derivs_12$start_index:indexes_derivs_12$`maxim(um/a)`]) %>%
mutate("index" = seq_along(speed)-1)
mp <- mp +
geom_line(data = derivs_12_data,
aes(x = index*4, y = speed*100), colour = cbp1_24[8]) +
geom_point(data = derivs_12_data,
aes(x = last(index)*4,
y = last(speed*100)),
colour = cbp1_24[8]) +
expand_limits(x = c(0, 160), y = c(0, 65)) +
ylab("Speed (cm/s)") +
xlab("Time (ms)") +
theme_bw()
Plot included speed changes for all trajectories
print(mp)
# mp+theme(panel.border = element_blank())
Max speeds for each spider and the elapsed time while going from 0 to to max.
results <- map_dfr(derivs_list_short, SpeedAndTime2)
# results %>% kbl() %>%
# kable_styling(full_width = F)
# rename("Max speed (cm/s)" = max_speed,
# "Elapsed time (ms)" = elapsed_time)
res_02 <- SpeedAndTime2(derivatives_list = derivs_list_special$Derivs_02, thresholdFrame = 19, window_size = 25, multiMax = 2)
res_12 <- SpeedAndTime2(derivatives_list = derivs_list_special$Derivs_12, thresholdFrame = 19, window_size = 35)
speeds_times <- bind_rows(results, res_02, res_12) %>%
mutate(camefrom = c(derivs_names_short, "Derivs_02", "Derivs_12"))
speeds_times %>% kbl() %>%
kable_styling(full_width = F)
| max_speed | elapsed_time | camefrom |
|---|---|---|
| 11.57657 | 116 | Derivs_01 |
| 29.94638 | 112 | Derivs_04 |
| 61.83679 | 132 | Derivs_05 |
| 19.86896 | 128 | Derivs_06 |
| 11.17088 | 96 | Derivs_07 |
| 21.52736 | 120 | Derivs_08 |
| 31.64278 | 104 | Derivs_09 |
| 33.36874 | 152 | Derivs_10 |
| 14.53998 | 92 | Derivs_11 |
| 29.30936 | 100 | Derivs_13 |
| 29.20735 | 104 | Derivs_14 |
| 15.24193 | 84 | Derivs_15 |
| 25.19305 | 108 | Derivs_16 |
| 33.06568 | 88 | Derivs_17 |
| 25.37552 | 108 | Derivs_18 |
| 23.51403 | 104 | Derivs_19 |
| 30.45109 | 92 | Derivs_20 |
| 22.21806 | 76 | Derivs_21 |
| 15.98763 | 108 | Derivs_22 |
| 24.35238 | 148 | Derivs_02 |
| 32.73323 | 96 | Derivs_12 |
speeds_times %>%
summarise(avgSpeed = mean(max_speed), avgTime = mean(elapsed_time))
# the median
table(speeds_times$elapsed_time)
##
## 76 84 88 92 96 100 104 108 112 116 120 128 132 148 152
## 1 1 1 2 2 1 3 3 1 1 1 1 1 1 1
median(speeds_times$elapsed_time)
## [1] 104
inset <- speeds_times %>%
ggplot() +
geom_boxplot(aes(elapsed_time)) +
expand_limits(x = c(0, 160)) +
theme( panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
# panel.background = element_blank(),
panel.background = element_rect(fill = "transparent",colour = NA),
plot.background = element_rect(fill = "transparent",colour = NA),
)
inset <- inset +
theme(legend.position = "none",
panel.grid = element_blank(),
axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
# rect = element_rect(fill = "transparent"),
# panel.background = element_blank(),
)
Panel F in figure 1 including inset box plot for elapsed time during speed change
# mp+geom_vline(xintercept = 104)+geom_vline(xintercept = 152) +
# inset_element (p = inset,
# left = -0.018,
# bottom = 0.80,
# right = 1.012,
# top = 0.95, align_to = "panel")
ggp_combi <- mp + theme_classic() +
inset_element (p = inset,
left = -0.018,
bottom = 0.89,
right = 1.012,
top = 0.99, align_to = "panel")
ggp_combi
# ggsave(filename = "panelF.pdf", plot = ggp_combi, device = "pdf", path = "./gg_plots")
# setwd("/Users/alfonsoaceves/Downloads/Ant Slayer Speed/gg_plots")
# write_csv(speeds_times, "speeds_times.csv")
# title: "R Notebook"
# output:
# html_document:
# code_folding: "show"
# toc: TRUE
# toc_float: TRUE
# df_print: paged
# editor_options:
# chunk_output_type: console